
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;                              klib.asm
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;                                                       Forrest Yu, 2005
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

; 导入全局变量
extern disp_pos

;[SECTION .data]
;disp_pos	dd	0

[SECTION .text]

; 导出函数
global disp_str
global disp_color_str
global out_byte
global in_byte

; ========================================================================
;                  void disp_str(char * info);
; ========================================================================
disp_str:
	push	ebp
	mov	ebp, esp

    push ebx ;\
    push esi ; |书上缺了这块，入栈保护，不然第二次调用 disp_str() 会乱码
    push edi ;/

	mov	esi, [ebp + 8]	; pszInfo
	mov	edi, [disp_pos]
	mov	ah, 0Fh
.1:
	lodsb
	test	al, al
	jz	.2
	cmp	al, 0Ah	; 是回车吗?
	jnz	.3
	push	eax
	mov	eax, edi
	mov	bl, 160
	div	bl
	and	eax, 0FFh
	inc	eax
	mov	bl, 160
	mul	bl
	mov	edi, eax
	pop	eax
	jmp	.1
.3:
	mov	[gs:edi], ax
	add	edi, 2
	jmp	.1

.2:
	mov	[disp_pos], edi

	pop	edi ;\
    pop esi ; | 恢复
    pop ebx ;/

    pop ebp
	ret

; ========================================================================
;                  void disp_color_str(char * info, int color);
; ========================================================================
disp_color_str:
	push	ebp
	mov	ebp, esp

    push ebx ;\
    push esi ; |书上缺了这块，入栈保护，不然第二次调用 disp_str() 会乱码
    push edi ;/

	mov	esi, [ebp + 8]	; pszInfo
	mov	edi, [disp_pos]
	mov	ah, [ebp + 12]	; color
.1:
	lodsb
	test	al, al
	jz	.2
	cmp	al, 0Ah	; 是回车吗?
	jnz	.3
	push	eax
	mov	eax, edi
	mov	bl, 160
	div	bl
	and	eax, 0FFh
	inc	eax
	mov	bl, 160
	mul	bl
	mov	edi, eax
	pop	eax
	jmp	.1
.3:
	mov	[gs:edi], ax
	add	edi, 2
	jmp	.1

.2:
	mov	[disp_pos], edi

	pop	edi ;\
    pop esi ; | 恢复
    pop ebx ;/

	pop	ebp
	ret

; ========================================================================
;                  void out_byte(u16 port, u8 value);
; ========================================================================
out_byte:
    mov     edx, [esp + 4]      ; port
    mov     al, [esp + 4 + 4]   ; value
    out     dx, al
    nop     ; 端口操作需要时间，nop 作为延迟
    nop
    ret

; ========================================================================
;                  u8 in_byte(u16 port);
; ========================================================================
in_byte:
    mov     edx, [esp + 4] ; port
    xor     eax, eax
    in      al, dx
    nop
    nop
    ret






